# A Spam Comment Filter plugin by Hirotaka Ogawa (http://as-is.net/blog/)
#
# Release 0.15 (Feb 1, 2005)
#
# This software is provided as-is. You may use it for commercial or 
# personal use. If you distribute it, please keep this notice intact.
#
# Copyright (c) 2005 Hirotaka Ogawa

use strict;

# Set your spam pattern
our $COMMENT_PATTERN = '<h1>|<a\s'; # H1 or A elements
our $TBPING_PATTERN = '<h1>|<a\s'; # H1 or A elements

# Choose a method for rejecting Spam Comments from: 
# 'CommentFilter', 'CommentThrottleFilter', 'CommentError',
# 'CommentLongError', 'CommentRedirect', 'CommentEvilRedirect'
our $COMMENT_METHOD = 'CommentFilter';

# Choose a method for rejecting Spam Pings from:
# 'TBPingFilter', 'TBPingThrottleFilter', 'TBPingError'
our $TBPING_METHOD = 'TBPingFilter';

# Set your Redirect URL (for 'Redirect' and 'EvilRedirect' methods)
our $URL = 'http://www.2ch.net/';

if (MT->can('add_plugin')) {
    require MT::Plugin;
    my $plugin = new MT::Plugin();
    $plugin->name("Quasi Spam Filter Plugin, v.0.15");
    $plugin->description("A Simple filter for Comment &amp; TBPing Spams");
    $plugin->doc_link("http://as-is.net/hacks/2005/01/quasi_spam_filter_plugin.html");
    MT->add_plugin($plugin);
}

if ($COMMENT_METHOD eq 'CommentFilter') {
    MT->add_callback('CommentFilter', 10, 'Reject Spam Comments',
		     \&comment_filter);
} elsif ($COMMENT_METHOD eq 'CommentThrottleFilter') {
    MT->add_callback('CommentThrottleFilter', 10, 'Reject Spam Comments',
		     \&comment_throttle_filter);
} elsif ($COMMENT_METHOD eq 'CommentError') {
    *MT::App::Comments::pre_run = \&comment_error;
} elsif ($COMMENT_METHOD eq 'CommentLongError') {
    *MT::App::Comments::pre_run = \&comment_long_error;
} elsif ($COMMENT_METHOD eq 'CommentRedirect') {
    *MT::App::Comments::pre_run = \&comment_redirect;
} elsif ($COMMENT_METHOD eq 'CommentEvilRedirect') {
    *MT::App::Comments::pre_run = \&comment_evil_redirect;
}

if ($TBPING_METHOD eq 'TBPingFilter') {
    MT->add_callback('TBPingFilter', 10, 'Reject Spam TBPings',
		     \&tbping_filter);
} elsif ($TBPING_METHOD eq 'TBPingThrottleFilter') {
    MT->add_callback('TBPingThrottleFilter', 10, 'Reject Spam TBPings',
		     \&tbping_throttle_filter);
} elsif ($TBPING_METHOD eq 'TBPingError') {
    *MT::App::Trackback::pre_run = \&tbping_error;
}

sub is_comment_spam {
    my $text = shift;
    return ($text =~ /$COMMENT_PATTERN/i);
}

sub is_tbping_spam {
    my $text = shift;
    return ($text =~ /$TBPING_PATTERN/i);
}

sub comment_filter {
    my ($eh, $app, $comment) = @_;
    return !is_comment_spam($comment->text);
}

sub comment_throttle_filter {
    my ($eh, $app, $entry) = @_;
    my $comment = $app->{query}->param('text');
    return !is_comment_spam($comment);
}

sub comment_error {
    my $app = shift;
    my $q = $app->{query};
    my $mode = $q->param('__mode') || $app->{default_mode};
    return if $mode ne 'post';
    if (is_comment_spam($q->param('text'))) {
        $app->add_methods(post => sub { });
        $app->error("Spam Comment!");
    }
}

sub comment_long_error {
    my $app = shift;
    my $q = $app->{query};
    my $mode = $q->param('__mode') || $app->{default_mode};
    return if $mode ne 'post';
    if (is_comment_spam($q->param('text'))) {
        $app->add_methods(post => sub { $_[0]->handle_error("Spam Comments!") });
    }
}

sub comment_redirect {
    my $app = shift;
    my $q = $app->{query};
    my $mode = $q->param('__mode') || $app->{default_mode};
    return if $mode ne 'post';
    if (is_comment_spam($q->param('text'))) {
        $app->add_methods(post => sub { });
        $app->redirect($URL);
    }
}

sub comment_evil_redirect {
    my $app = shift;
    my $q = $app->{query};
    my $mode = $q->param('__mode') || $app->{default_mode};
    return if $mode ne 'post';
    if (is_comment_spam($q->param('text'))) {
        $app->add_methods(post => sub { });
        $app->redirect($q->param('url') || $URL);
    }
}

sub tbping_filter {
    my ($eh, $app, $ping) = @_;
    return !is_tbping_spam($ping->excerpt);
}

sub tbping_throttle_filter {
    my ($eh, $app, $tb) = @_;
    my $q = $app->{query};
    return !is_tbping_spam($q->param('excerpt'));
}

sub tbping_error {
    my $app = shift;
    my $q = $app->{query};
    my $mode = $q->param('__mode') || $app->{default_mode};
    return if $mode ne 'ping';
    if (is_tbping_spam($q->param('excerpt'))) {
	$app->add_methods('ping' => sub { });
	$app->_response(Error => 'Spam TBPing!', Code => 403);
    }
}

1;
